package com.snail.common.core.utils;

import com.sun.management.OperatingSystemMXBean;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.util.Formatter;

/**
 * @Description: 服务器工具类
 * @Author: Snail
 * @CreateDate: 2023/8/1 16:33
 * @Version: V1.0
 */
public class ServerUtil {
    private static final int BYTE_TO_KB = 1024;

    private static final int BYTE_TO_MB = 1024 * 1024;

    private static final int BYTE_TO_GB = 1024 * 1024 * 1024;

    private static final String CMD = "cat /proc/net/dev";

    private static final String WINCMD = "netstat -e";

    /**
     * 获取操作系统名称
     *
     * @return
     */
    public static String getOsName() {
        return System.getProperty("os.name");
    }

    /**
     * 获取系统cpu负载(百分比不带百分号)
     *
     * @return
     */
    public static double getSystemCpuLoad() {
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        double systemCpuLoad = osmxb.getSystemCpuLoad() * 100;
        return formatNumber(systemCpuLoad);
    }

    /**
     * 获取物理内存负载(百分比不带百分号)
     *
     * @return
     */
    public static double getMemoryLoad() {
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        double totalMemorySize = osmxb.getTotalPhysicalMemorySize() / BYTE_TO_MB;
        double usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb.getFreePhysicalMemorySize()) / BYTE_TO_MB;
        double memorySizeLoad = usedMemory / totalMemorySize * 100;
        return formatNumber(memorySizeLoad);
    }

    /**
     * 获取总的物理内存（单位:M）
     *
     * @return
     */
    public static long getTotalMemorySize() {
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        long totalMemorySize = osmxb.getTotalPhysicalMemorySize() / BYTE_TO_MB;
        return totalMemorySize;
    }

    /**
     * 获取剩余的物理内存（单位:M）
     *
     * @return
     */
    public static long getFreePhysicalMemorySize() {
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize() / BYTE_TO_MB;
        return freePhysicalMemorySize;
    }

    /**
     * 获取已使用的物理内存（单位:M）
     *
     * @return
     */
    public static long getUsedMemory() {
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        long usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb.getFreePhysicalMemorySize()) / BYTE_TO_MB;
        return usedMemory;
    }

    /**
     * JVM内存负载(百分比不带百分号)
     *
     * @return
     */
    public static double getJvmMemoryLoad() {
        Runtime rt = Runtime.getRuntime();
        long jvmTotal = rt.totalMemory();
        long jvmFree = rt.freeMemory();
        long jvmUse = jvmTotal - jvmFree;
        double jvmMemoryLoad = (double) jvmUse / jvmTotal * 100;
        return formatNumber(jvmMemoryLoad);
    }

    /**
     * 获取jvm线程负载(百分比不带百分号)
     *
     * @return
     */
    public static double getProcessCpuLoad() {
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        double ProcessCpuLoad = osmxb.getProcessCpuLoad() * 100;
        return formatNumber(ProcessCpuLoad);
    }

    /**
     * JVM内存的空闲空间（单位:M）
     *
     * @return
     */
    public static long getJvmFreeMemory() {
        Runtime rt = Runtime.getRuntime();
        long jvmFree = rt.freeMemory() / BYTE_TO_MB;
        return jvmFree;
    }

    /**
     * JVM内存已用的空间（单位:M）
     *
     * @return
     */
    public static long getJvmUseMemory() {
        Runtime rt = Runtime.getRuntime();
        long jvmTotal = rt.totalMemory() / BYTE_TO_MB;
        long jvmFree = rt.freeMemory() / BYTE_TO_MB;
        long jvmUse = jvmTotal - jvmFree;
        return jvmUse;
    }

    /**
     * JVM总内存空间（单位:M）
     *
     * @return
     */
    public static long getJvmTotalMemory() {
        Runtime rt = Runtime.getRuntime();
        long jvmTotal = rt.totalMemory() / BYTE_TO_MB;
        return jvmTotal;
    }

    /**
     * JVM最大能够申请的内存（单位:M）
     *
     * @return
     */
    public static long getJvmMaxMemory() {
        Runtime rt = Runtime.getRuntime();
        long jvmMax = rt.maxMemory() / BYTE_TO_MB;
        return jvmMax;
    }

    /**
     * 获取磁盘大小（单位：G）
     *
     * @return
     */
    public static long getTotalDisk() {
        // 获取磁盘分区列表
        File[] roots = File.listRoots();
        long total = 0;
        for (File file : roots) {
            total += file.getTotalSpace();
        }
        return total / BYTE_TO_GB;
    }

    /**
     * 获取磁盘已使用大小（单位：G）
     *
     * @return
     */
    public static long getUsedDisk() {
        // 获取磁盘分区列表
        File[] roots = File.listRoots();
        long free = 0;
        long total = 0;
        for (File file : roots) {
            free += file.getFreeSpace();
            total += file.getTotalSpace();
        }
        long used = (total - free) / BYTE_TO_GB;
        return used;
    }

    /**
     * 获取磁盘未使用大小（单位：G）
     *
     * @return
     */
    public static long getFreeSpace() {
        // 获取磁盘分区列表
        File[] roots = File.listRoots();
        long free = 0;
        for (File file : roots) {
            free += file.getFreeSpace();
        }
        return free / BYTE_TO_GB;
    }

    /**
     * 获取磁盘负载（单位：G）
     *
     * @return
     */
    public static double getDiskLoad() {
        // 获取磁盘分区列表
        File[] roots = File.listRoots();
        long freeTotal = 0;
        long total = 0;
        for (File file : roots) {
            freeTotal += file.getFreeSpace();
            total += file.getTotalSpace();
        }
        long useTotal = total - freeTotal;
        double spaceLoad = (double) useTotal / total * 100;
        return formatNumber(spaceLoad);
    }

    /**
     * 格式化浮点数保留两位小数
     *
     * @param d
     * @return
     */
    private static double formatNumber(double d) {
        return Double.parseDouble(new Formatter().format("%.2f", d).toString());
    }

    public static String printInfo(){
        return "===============================================================================================\n" +
                "操作系统:" + getOsName() + "\n" +
                "磁盘大小:" + getTotalDisk() + "G\n" +
                "磁盘已使用:" + getUsedDisk() + "G\n" +
                "JVM总内存:" + getJvmTotalMemory() + "M\n" +
                "JVM已使用:" + getJvmUseMemory() + "M\n" +
                "JVM可使用:" + getJvmFreeMemory() + "M\n" +
                "物理总内存:" + getTotalMemorySize() + "M\n" +
                "物理内存剩余:" + getFreePhysicalMemorySize() + "M\n" +
                "物理内存已使用:" + getUsedMemory() + "M\n" +
                "物理内存负载:" + getMemoryLoad() + "%\n" +
                "===============================================================================================";
    }
}
